package com.ashlikun.pdfview.sample

import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.provider.OpenableColumns
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.ashlikun.pdfview.FitPolicy
import com.ashlikun.pdfview.PDFView
import com.ashlikun.pdfview.model.PdfBookmark
import com.ashlikun.pdfview.scroll.DefaultScrollHandle
import com.ashlikun.pdfview.source.AssetSource
import com.ashlikun.pdfview.util.PdfViewUtil
import com.ashlikun.pdfview.sample.databinding.ActivityMainBinding

class PDFViewActivity : AppCompatActivity() {
    val binding by lazy {
        ActivityMainBinding.inflate(layoutInflater)
    }
    val pdfView: PDFView by lazy {
        binding.pdfView
    }

    var uri: Uri? = null

    var pageNumber = 10
    var pdfFileName: String? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        PdfViewUtil.DEBUG_MODE = true
        setContentView(binding.root)
        displayFromAsset(SAMPLE_FILE)
        binding.testBtn.setOnClickListener {
            binding.pdfView.jumpTo((0..80).random(), true)
        }
    }

    fun pickFile() {
        val permissionCheck = ContextCompat.checkSelfPermission(
            this,
            READ_EXTERNAL_STORAGE
        )
        if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(
                this, arrayOf(READ_EXTERNAL_STORAGE),
                PERMISSION_CODE
            )
            return
        }
        launchPicker()
    }

    fun launchPicker() {
        val intent = Intent(Intent.ACTION_GET_CONTENT)
        intent.setType("application/pdf")
        try {
            startActivityForResult(intent, REQUEST_CODE)
        } catch (e: ActivityNotFoundException) {
            //alert user that file manager not working
            Toast.makeText(this, R.string.toast_pick_file_error, Toast.LENGTH_SHORT).show()
        }
    }

    fun afterViews() {
        pdfView.setBackgroundColor(Color.LTGRAY)
        if (uri != null) {
            displayFromUri(uri)
        } else {
            displayFromAsset(SAMPLE_FILE)
        }
        title = pdfFileName
    }

    private fun displayFromAsset(assetFileName: String) {
        pdfFileName = assetFileName
        pdfView.currentPage = pageNumber
        pdfView.config.apply {
            callbacks.onPageChange = { page, pageCount ->
                pageNumber = page
                val title = String.format("%s %s / %s", pdfFileName, page + 1, pageCount)
                PdfViewUtil.logi("onPageChanged  ${title}")
            }
            callbacks.onLoadComplete = { nbPages ->
                PdfViewUtil.logi("loadComplete nbPages = $nbPages")
                val meta = pdfView.documentMeta
                if (meta != null) {
                    Log.e(TAG, "title = " + meta.title)
                    Log.e(TAG, "author = " + meta.author)
                    Log.e(TAG, "subject = " + meta.subject)
                    Log.e(TAG, "keywords = " + meta.keywords)
                    Log.e(TAG, "creator = " + meta.creator)
                    Log.e(TAG, "producer = " + meta.producer)
                    Log.e(TAG, "creationDate = " + meta.creationDate)
                    Log.e(TAG, "modDate = " + meta.modDate)
                }
                printBookmarksTree(pdfView.tableOfContents, "-")
            }
            callbacks.onPageError = { page, t ->
                t?.printStackTrace()
                PdfViewUtil.logi("onPageError page = $page")
            }
//            callbacks.onGetPageSize = { width, height ->
//                Size(width * 2, height * 2)
//            }

            isAnnotationRendering = true
            scrollHandle = DefaultScrollHandle(this@PDFViewActivity)
            isVertical = true
            isPageSnap = false
            isPageFling = false
            isAutoSpacing = false
            isFitEachPage = false
            spacing = PdfViewUtil.getDP(this@PDFViewActivity, 10) // in dp
            pageFitPolicy = FitPolicy.WIDTH
//            userPages = intArrayOf(1, 3, 4, 5, 6, 9)
            docSource = AssetSource(SAMPLE_FILE)
        }
        pdfView.load()
    }

    private fun displayFromUri(uri: Uri?) {
        pdfFileName = getFileName(uri)
//        pdfView.fromUri(uri)
//            .defaultPage(pageNumber)
//            .onPageChange(this)
//            .enableAnnotationRendering(true)
//            .onLoad(this)
//            .swipeHorizontal(true)
//            .scrollHandle(DefaultScrollHandle(this))
//            .spacing(10) // in dp
//            .onPageError(this)
//            .load()
    }

    fun onResult(resultCode: Int, intent: Intent) {
        if (resultCode == Activity.RESULT_OK) {
            uri = intent.getData()
            displayFromUri(uri)
        }
    }


    fun getFileName(uri: Uri?): String? {
        var result: String? = null
        if (uri!!.scheme == "content") {
            val cursor = contentResolver.query(uri, null, null, null, null)
            try {
                if (cursor != null && cursor.moveToFirst()) {
                    result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME))
                }
            } finally {
                cursor?.close()
            }
        }
        if (result == null) {
            result = uri.lastPathSegment
        }
        return result
    }


    fun printBookmarksTree(tree: List<PdfBookmark>, sep: String) {
        for (b in tree) {
            Log.e(TAG, String.format("%s %s, p %d", sep, b.title, b.pageIdx))
            if (b.hasChildren()) {
                printBookmarksTree(b.children, "$sep-")
            }
        }
    }

    /**
     * Listener for response to user permission request
     *
     * @param requestCode  Check that permission request code matches
     * @param permissions  Permissions that requested
     * @param grantResults Whether permissions granted
     */
    override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<String>,
        grantResults: IntArray
    ) {
        if (requestCode == PERMISSION_CODE) {
            if (grantResults.size > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED
            ) {
                launchPicker()
            }
        }
    }

    companion object {
        private val TAG = PDFViewActivity::class.java.simpleName
        private const val REQUEST_CODE = 42
        const val PERMISSION_CODE = 42042
        const val SAMPLE_FILE = "sample.pdf"
        const val READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE"
    }
}
